package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.exception.CustException;
import com.heima.file.service.FileStorageService;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.media.pojos.WmUser;
import com.heima.model.threadlocal.WmThreadLocalUtils;
import com.heima.model.wmmedia.dtos.WmMaterialDTO;
import com.heima.model.wmmedia.pojos.WmMaterial;
import com.heima.model.wmmedia.pojos.WmNewsMaterial;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmMaterialService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

@Service
@Slf4j
public class WmMaterialServiceImpl extends ServiceImpl<WmMaterialMapper, WmMaterial> implements WmMaterialService {
    @Autowired
    private WmMaterialMapper wmMaterialMapper;
    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;
    @Autowired
    private FileStorageService fileStorageService;
    //从nacos的share-file.yml读取属性
    @Value("${file.oss.prefix}")  //"material"
    String prefix;
    @Value("${file.oss.web-site}")  //"http://hmleadnewswxd.oss-cn-beijing.aliyuncs.com"  前缀访问路径
    String webSite;

    //图片上传
    @Override
    public ResponseResult uploadPicture(MultipartFile multipartFile) {
        //非空判断
        if (multipartFile == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID, "文件上传异常!");
        }
        //从线程获取用户
        WmUser user = WmThreadLocalUtils.getUser();
        //非空判断
        if (user == null) {
            CustException.cust(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        //获取上传文件的文件名
        String originalFilename = multipartFile.getOriginalFilename();
        //校验文件后缀名类型
        if (!checkFileName(originalFilename)) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID, "文件类型错误!");
        }
        //获取后缀名  获取原文件名最后一个.的索引并切割到末尾
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));  //.xxx
        //使用UUID生成文件ID  替换掉-符号
        String fileName = UUID.randomUUID().toString().replace("-", "") + suffix;  //xxx.xxx
        String url = null;
        try {
            //上传到OSS  获取文件路径
            url = fileStorageService.store(prefix, fileName, multipartFile.getInputStream());
        } catch (IOException e) {
            CustException.cust(AppHttpCodeEnum.SERVER_ERROR, "文件上传失败!");
        }
        //文件上传成功  信息保存到数据库
        WmMaterial wmMaterial = new WmMaterial();
        wmMaterial.setUserId(user.getId());
        wmMaterial.setType((short) 0);  //文件类型  0:图片  1:视频
        wmMaterial.setIsCollection((short) 0);  //是否收藏  否
        wmMaterial.setCreatedTime(new Date());
        wmMaterial.setUrl(url);
        //插入数据库
        wmMaterialMapper.insert(wmMaterial);
        //前端显示用
        wmMaterial.setUrl(webSite + url);
        //响应前端
        return ResponseResult.okResult(wmMaterial);
    }

    //素材列表加载
    @Override
    public ResponseResult findList(WmMaterialDTO dto) {
        //非空判断
        if (dto == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        //创建分页对象
        IPage<WmMaterial> page = new Page<>(dto.getPage(), dto.getSize());
        //创建Wrapper
        LambdaQueryWrapper<WmMaterial> wrapper = Wrappers.lambdaQuery();
        //判断收藏参数
        if (dto.getIsCollection() == 1) {
            //查询收藏
            wrapper.eq(WmMaterial::getIsCollection, dto.getIsCollection());
        }
        //获取当前登录的用户id
        Integer id = WmThreadLocalUtils.getUser().getId();
        //非空判断
        if (id == null) {
            CustException.cust(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        //设置条件
        wrapper.eq(WmMaterial::getUserId, id);  //当前用户的
        wrapper.orderByDesc(WmMaterial::getCreatedTime);
        //开始查询
        IPage<WmMaterial> wmMaterialIPage = wmMaterialMapper.selectPage(page, wrapper);
        List<WmMaterial> wmMaterials = wmMaterialIPage.getRecords();
        //非空判断
        if (wmMaterials == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //给图片加上前缀访问路径
        for (WmMaterial wmMaterial : wmMaterials) {
            wmMaterial.setUrl(webSite + wmMaterial.getUrl());
        }
        //封装结果
        PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(), dto.getSize(), wmMaterialIPage.getTotal(), wmMaterials);
        return pageResponseResult;
    }

    //图片删除
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deletePic(Integer id) {
        //非空判断
        if (id == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        //根据素材Id查询wm_material表
        WmMaterial wmMaterial = wmMaterialMapper.selectById(id);
        if (wmMaterial == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "不存在该素材!");
        }
        //有素材,再查询wm_news_material表
        LambdaQueryWrapper<WmNewsMaterial> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(WmNewsMaterial::getMaterialId, id);
        WmNewsMaterial wmNewsMaterial = wmNewsMaterialMapper.selectOne(wrapper);
        //判断是否存在
        if (wmNewsMaterial != null) {
            //图片被引用,不能删除
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "该图片被引用,无法删除!");
        }
        //图片没有被引用,可以删除
        wmMaterialMapper.deleteById(id);
        //删除OSS
        fileStorageService.delete(wmMaterial.getUrl());
        //响应前端
        return ResponseResult.okResult();
    }

    //收藏图片
    @Override
    public ResponseResult isCollect(Integer id, short isCol) {
        //非空判断
        if (id == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        //根据素材id查询
        WmMaterial wmMaterial = wmMaterialMapper.selectById(id);
        //判断
        if (wmMaterial == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "该素材不存在!");
        }
        //根据素材id和当前用户id查询数据库
//        LambdaQueryWrapper<WmMaterial> wrapper = Wrappers.lambdaQuery();
//        wrapper.eq(WmMaterial::getUserId,WmThreadLocalUtils.getUser());
//        wrapper.eq(WmMaterial::getId,id);
//        WmMaterial wmMaterial = wmMaterialMapper.selectOne(wrapper);
        //获取当前用户
        Integer id1 = WmThreadLocalUtils.getUser().getId();
        //判断该素材是否是当前用户的
        if (!wmMaterial.getUserId().equals(id1)) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "只允许修改自己上传的素材!");
        }
        //存在素材,修改
        wmMaterial.setIsCollection(isCol);
        //插入数据库
        wmMaterialMapper.updateById(wmMaterial);
        //返回前端
        return ResponseResult.okResult();
    }

    //校验文件名
    public boolean checkFileName(String path) {
        //非空判断
        if (path == null) {
            return false;
        }
        //创建集合,放入白名单类型
        List<String> suffixList = Arrays.asList("jpg", "jpeg", "png", "gif");
        Boolean checkCode = false;
        //遍历集合
        for (String suf : suffixList) {
            //校验后缀名  相同则返回
            if (path.endsWith(suf)) {
                checkCode = true;
            }
        }
        return checkCode;
    }
}